﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace Passion3DProject.src.About_the_Camera
{
    class FirstPersonCamera : Camera
    {
        private float UpDownRotation = -MathHelper.Pi / 10.0f;
        private float leftRightRotation = MathHelper.PiOver2;
        private Vector3 cameraRotatedVector;
        

        public Vector3 CameraRotatedVector
        {
          get { return cameraRotatedVector; }
          set { cameraRotatedVector = value; }
        }
        
        public float LeftRightRotation
        {
            get { return leftRightRotation; }
            set { leftRightRotation = value; }
        }

        private float rot = 0.0f;
        /// <summary>
        /// 
        /// </summary>
        public float Rot
        {
            get { return rot; }
            set { rot = value; }
        }

        private float rotSpeed = 0.003f;
        private GraphicsDeviceManager graphics;

        public  FirstPersonCamera(GraphicsDeviceManager graphics)
            :base(graphics)
        {
            this.graphics = graphics;

            this.NearestDistance = 1.0f;
            this.MaxDistance = 300.0f;
            
            this.Target = Vector3.Zero;
            this.Orientation = Vector3.Up;
            this.CameraGapAngle = 45.0f;

            this.PlayerDistance = new Vector3(0, 0, -3);
            this.AspectRatio = Game1.AspectRatio;

            this.WorldCamMatrix = Matrix.Identity;
            this.viewMatrix = Matrix.CreateLookAt(Position, Target, Orientation);

            this.ProjectionCamMatrix = Matrix.CreatePerspectiveFieldOfView(
                CameraGapAngle,
                AspectRatio,
                NearestDistance,
                MaxDistance);

            Mouse.SetPosition(
                graphics.GraphicsDevice.DisplayMode.Width / 2,
                graphics.GraphicsDevice.DisplayMode.Height / 2);

            Engine.originalMouseState = Mouse.GetState();            
        }

        public void Update(Vector3 playerPosition,Vector3 moveVector)
        {
            Engine.currentMouseState = Mouse.GetState();
            Rot = 0.0f;

            if (Engine.currentMouseState != Engine.originalMouseState)
            {
                float xDifference = Engine.currentMouseState.X - Engine.originalMouseState.X;
                float yDifference = Engine.currentMouseState.Y - Engine.originalMouseState.Y;
                
                leftRightRotation -= rotSpeed * xDifference;
                UpDownRotation -= rotSpeed * yDifference;

                Mouse.SetPosition(
                    graphics.GraphicsDevice.Viewport.Width / 2,
                    graphics.GraphicsDevice.Viewport.Height / 2);
            }

            //[...]
            this.RotationMatrix = Matrix.CreateRotationX(UpDownRotation) * Matrix.CreateRotationY(leftRightRotation);
            //RotationY = Matrix.CreateRotationY(leftRightRotation);
            //Transformação da matriz em um vetor para que a câmera se mova na direção que o mouse está olhando
            CameraRotatedVector = Vector3.Transform(PlayerDistance, RotationMatrix);
            
            //Atualiza a Posição da Câmera
            this.Position = playerPosition + CameraRotatedVector;
            
            //[...]
            Vector3 originalCameraTarget = new Vector3(0, 0, -1);
            Vector3 RotatedTarget = Vector3.Transform(originalCameraTarget, RotationMatrix);
            this.Target = playerPosition + RotatedTarget;

            //Resetando A Orientação da Câmera
            this.Orientation = Vector3.Up;
            //Ajust da Orientação da Câmera
            this.Orientation = Vector3.Transform(this.Orientation, RotationMatrix);
            
            //Atualiza o VIEW da câmera em função da sua posição, target e orientação
            viewMatrix = Matrix.CreateLookAt(this.Position, this.Target, this.Orientation);

            //Atualiza a Projeção da câmera
            ProjectionCamMatrix = Matrix.CreatePerspectiveFieldOfView(
                CameraGapAngle,
                AspectRatio,
                NearestDistance,
                MaxDistance);
        }
    }
}
